import { ts,  NodePredicate } from 'qvog-dsl';
import { native, HomeCheckHint } from 'qvog-dsl';

const SEVERITY = 2;
const DOC_PATH = 'docs/no-array-constructor-ts.md';
const DESCRIPTION = 'The array literal notation [] is preferable';

const ArrayConstructorNode: NodePredicate<ts.CallExpression | ts.NewExpression> = {
  is(node: ts.Node): node is ts.CallExpression | ts.NewExpression {
    if (!ts.isCallExpression(node) && !ts.isNewExpression(node)) {
      return false;
    }
    const callee = node.expression;
    return ts.isIdentifier(callee) && callee.text === 'Array';
  }
};

export default native<HomeCheckHint>()()
  .match(ArrayConstructorNode)
  .when((node: ts.CallExpression | ts.NewExpression): boolean => {
    if (node.typeArguments?.length) { return false };

    if (isLocalArray(node.expression)) { return false };
    if (node.arguments?.length === 1 && isNumberArgument(node.arguments[0])) {
      return false;
    }

    return true;
  })
  .report({
    severity: SEVERITY,
    description: DESCRIPTION,
    docPath: DOC_PATH,
  });

// 辅助函数
function isLocalArray(node: ts.Node): boolean {
  let current = node.parent;
  while (current) {
    if (ts.isVariableDeclaration(current) && current.name === node) {
      return true;
    }
    current = current.parent;
  }
  return false;
}

function isNumberArgument(node: ts.Expression): boolean {
  return ts.isNumericLiteral(node) ||
    (ts.isIdentifier(node) && /^\d+$/.test(node.text));
}